/**
 *Klasa pomocnicza przy dwukierunkowej komunikacji Klient-Serwer. Stanowi opakowanie metod biblioteki GCF.
 */

package bt;

import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import java.io.*;

// TO DO: WYMYSLIJ SPOSOB NA ODCZYT OBRAZKOW !!! //

public class BluetoothConnection {

    private StreamConnection streamConnection;
    private InputStream inputStream;
    private OutputStream outputStream;
    private String localName;
    private String remoteName;
    private String url;

    public BluetoothConnection(StreamConnection con, String ln, String rn) throws IOException {
        localName = ln;
        remoteName = rn;
        url = "";
        streamConnection = con;
        openStreams();
    }

    public BluetoothConnection(String urlStrings, String ln, String rn) throws IOException {
        localName = ln;
        remoteName = rn;
        url = urlStrings;
        connect();
    }

    private void connect() {
        try {
            streamConnection = (StreamConnection) Connector.open(url);
            openStreams();
        } catch (Exception e) {
        }
    }

    private void openStreams()
            throws IOException {
        inputStream = streamConnection.openInputStream();
        outputStream = streamConnection.openOutputStream();
    }

    synchronized public void close() {
        try {
            outputStream.close();
        } catch (IOException e) {
            // I tak tu wiele sie zrobic nie da
        }

        try {
            inputStream.close();
        } catch (IOException e) {
            // I tak tu wiele sie zrobic nie da
        }

        try {
            if (streamConnection != null) {
                streamConnection.close();
                streamConnection = null;
            }
        } catch (IOException e) {
            // I tak tu wiele sie zrobic nie da
        }
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public OutputStream getOutputStream() {
        return outputStream;
    }

    public String getLocalName() {
        return localName;
    }

    public String getRemoteName() {
        return remoteName;
    }

    protected void setRemoteName(String rn) {
        remoteName = rn;
    }

    public void writeString(String s) throws IOException {
        byte[] bytes = s.getBytes();
        outputStream.write(bytes.length);
        outputStream.write(bytes);
        outputStream.flush();
    }

    public String readString() throws IOException {
        int length = inputStream.read();
        byte[] bytes = new byte[length];
        read(bytes, length);
        return new String(bytes);
    }

    public void writeInt(int v) throws IOException {
        outputStream.write((v & 0xFF));
        outputStream.write(((v >> 8) & 0xFF));
        outputStream.write(((v >> 16) & 0xFF));
        outputStream.write(((v >> 24) & 0xFF));
    }

    public int readInt() throws IOException {
        int res;
        res = inputStream.read();
        res += inputStream.read() << 8;
        res += inputStream.read() << 16;
        res += inputStream.read() << 24;
        return res;
    }

    public void writeImage(String imageName) {
        byte[] imgData = ImagetoBytes(imageName);

        try {
            outputStream.write(imgData.length >> 8);
            outputStream.write(imgData.length & 0xff);
            outputStream.write(imgData);
            outputStream.flush();
        } catch (IOException e) {
            System.err.println("Nie mozna przeslac obrazu: " + e);
        }
    }

    private byte[] ImagetoBytes(String imageName) {
        InputStream in = this.getClass().getResourceAsStream(imageName);
        byte[] buff = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);

        try {
            while (true) {
                int length = in.read(buff);

                if (length == -1) {
                    break;
                }

                baos.write(buff, 0, length);
            }
        } catch (IOException e) {
            System.err.println("Nie mozna pobrac obraka: imgName=" + imageName + " :" + e);

            return null;
        }

        return baos.toByteArray();
    }

    public Image readImage() {
        byte[] imgData = null;

        try {
            int length = inputStream.read() << 8;
            length |= inputStream.read();

            if (length <= 0) {
                throw new IOException("Nie mozna odczytac dlugosci danych");
            }

            imgData = new byte[length];
            length = 0;

            while (length != imgData.length) {
                int n = inputStream.read(imgData, length, imgData.length - length);

                if (n == -1) {
                    throw new IOException("Nie mozna odczytac obrazka");
                }

                length += n;
            }

        } catch (IOException e) {
            System.err.println("Nie da rady odczytać danych z serwera: " + url);
        } finally {
        }

        Image img = null;

        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(imgData);
//            img = ImageIO.read(bais);
        } catch (Exception e) {
            // may be next time
            System.err.println("Bład! Błędne dane graficze od: " + url);
        }

        return img;
    }

    /** Zwraca true jesli polaczenie jest zamkniete, false jesli nie jest
     */
    public boolean isClosed() {
        if (streamConnection == null) {
            // is closed
            return true;
        } else {
            // is still open
            return false;
        }
    }

    /** Czyta len bajtów do tablicy arr  */
    public void read(byte[] arr, int len) throws IOException {
        int offs, count;

        offs = 0;
        while (len > 0) {
            count = inputStream.read(arr, offs, len);
            len -= count;
            offs += count;
        }
    }
}
